package com.dt.platform.hr.service.impl;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONObject;
import com.dt.platform.constants.enums.common.StatusEnableEnum;
import com.dt.platform.constants.enums.common.YesNoEnum;
import com.dt.platform.constants.enums.hr.LearnTaskStatusEnum;
import com.dt.platform.constants.enums.hr.PaperQuestionModeEnum;
import com.dt.platform.constants.enums.hr.PaperTaskResultStatusEnum;
import com.dt.platform.constants.enums.hr.ReleaseStatusEnum;
import com.dt.platform.domain.hr.*;
import com.dt.platform.domain.hr.meta.PaperMeta;
import com.dt.platform.domain.hr.meta.PaperReleaseMeta;
import com.dt.platform.hr.service.*;
import com.github.foxnic.commons.lang.StringUtil;
import com.github.foxnic.dao.data.RcdSet;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.foxnic.dao.entity.ReferCause;
import com.github.foxnic.commons.collection.MapUtil;

import java.util.*;


import com.github.foxnic.api.transter.Result;
import com.github.foxnic.dao.data.PagedList;
import com.github.foxnic.dao.entity.SuperService;
import com.github.foxnic.dao.spec.DAO;
import java.lang.reflect.Field;
import com.github.foxnic.commons.busi.id.IDGenerator;
import com.github.foxnic.sql.expr.ConditionExpr;
import com.github.foxnic.api.error.ErrorDesc;
import com.github.foxnic.dao.excel.ExcelWriter;
import com.github.foxnic.dao.excel.ValidateResult;
import com.github.foxnic.dao.excel.ExcelStructure;
import java.io.InputStream;
import com.github.foxnic.sql.meta.DBField;
import com.github.foxnic.dao.data.SaveMode;
import com.github.foxnic.dao.meta.DBColumnMeta;
import com.github.foxnic.sql.expr.Select;

import org.github.foxnic.web.framework.dao.DBConfigs;

/**
 * <p>
 * 考试下发服务实现
 * </p>
 * @author 金杰 , maillank@qq.com
 * @since 2024-09-14 13:53:00
*/


@Service("HrPaperReleaseService")

public class PaperReleaseServiceImpl extends SuperService<PaperRelease> implements IPaperReleaseService {


	@Autowired
	private IPaperService paperService;

	@Autowired
	private IPaperQuestionRelService paperQuestionRelService;


	@Autowired
	private IPaperTaskService paperTaskService;

	/**
	 * 注入DAO对象
	 * */
	@Resource(name=DBConfigs.PRIMARY_DAO) 
	private DAO dao=null;

	/**
	 * 获得 DAO 对象
	 * */
	public DAO dao() { return dao; }



	@Override
	public Object generateId(Field field) {
		return IDGenerator.getSnowflakeIdString();
	}



	/**
	 * 添加，根据 throwsException 参数抛出异常或返回 Result 对象
	 *
	 * @param paperRelease  数据对象
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 结果 , 如果失败返回 false，成功返回 true
	 */
	@Override
	public Result insert(PaperRelease paperRelease,boolean throwsException) {

		Paper paper=paperService.getById(paperRelease.getPaperId());
		dao.fill(paper).with(PaperMeta.PAPER_QUESTION_REAL_LIST).execute();
		List<PaperQuestionRel> list=paper.getPaperQuestionRealList();

		String sourcePaperId=paper.getId();
		String afterPaperId="";
		//备份试卷
		Result paperRes=paperService.createPaper(sourcePaperId);
		if(paperRes.isSuccess()){
			JSONObject obj= (JSONObject) paperRes.getData();
			afterPaperId=obj.getString("id");
		}else{
			return paperRes;
		}
		paperRelease.setPaperId(afterPaperId);
		paperRelease.setSourcePaperId(sourcePaperId);
		paperRelease.setRcdTime(new Date());
		paperRelease.setCode(IDGenerator.getRandomDigits(8));
		paperRelease.setStatus(StatusEnableEnum.ENABLE.code());
		paperRelease.setCost(paper.getCost());
		paperRelease.setSdate(new Date());
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, 7);
		paperRelease.setEdate(calendar.getTime());
		paperRelease.setLearnId(paper.getLearnId());
		paperRelease.setIfLearn(paper.getIfLearn());
		paperRelease.setIfAllUser(YesNoEnum.no.code());
		paperRelease.setReleaseStatus(ReleaseStatusEnum.NOT_DISTRIBUTE.code());
		Result r=super.insert(paperRelease,throwsException);

		return r;
	}

	@Override
	public Result release(String id) {
		PaperRelease release=this.getById(id);
		dao.fill(release).with(PaperReleaseMeta.PAPER).execute();
		if(ReleaseStatusEnum.CANCEL.code().equals(release.getReleaseStatus())){
			return ErrorDesc.failureMessage("已作废,无法下发");
		}

		String userSql="";
		RcdSet rs=null;
		if("yes".equals(release.getIfAllUser())){
			//全部用户
			userSql="select a.id from hrm_employee a,sys_user_tenant b where a.deleted=0 and a.badge<>'system' and a.status='active'  and a.id=b.employee_id\n";
			rs=dao.query(userSql);
		}else{
			//选择的用户
			userSql="select selected_code id from sys_mapping_owner where deleted=0 and owner='user' and owner_id=?";
			rs=dao.query(userSql,release.getId());
		}

		if(rs.size()==0){
			return ErrorDesc.failureMessage("没有可下发用户,请先选择下发范围");
		}

		Paper paper=release.getPaper();
		if(paper==null){
			return ErrorDesc.failureMessage("未找到试卷");
		}
		//下发策略，如果已完成任务，则跳过，不覆盖，目前只选择一种
		for(int i=0;i<rs.size();i++){
			//如果是抽题模式，在发任务时生成试卷
			String rPaperId=release.getPaperId();
			if(PaperQuestionModeEnum.FIX.code().equals(paper.getQuestionMode())){
				rPaperId=release.getPaperId();
			}else if(PaperQuestionModeEnum.RAND.code().equals(paper.getQuestionMode())){
				Result paperRes=paperService.createPaper(release.getPaperId());
				if(paperRes.isSuccess()){
					JSONObject obj= (JSONObject)paperRes.getData();
					rPaperId=obj.getString("id");
				}else{
					return paperRes;
				}
			}
			PaperTask queryTask=new PaperTask();
			queryTask.setUserId(rs.getRcd(i).getString("id"));
			queryTask.setPaperReleaseId(id);
			PaperTask task=paperTaskService.queryEntity(queryTask);
			if(task==null){
				PaperTask obj=new PaperTask();
				obj.setName(release.getPaper().getName());
				obj.setStatus(LearnTaskStatusEnum.RELEASED.code());
				obj.setPaperStatus(PaperTaskResultStatusEnum.NOT_ACT.code());
				obj.setPaperId(rPaperId);
				obj.setPaperReleaseId(id);
				obj.setUserId(rs.getRcd(i).getString("id"));
				paperTaskService.insert(obj,false);
			}else{
			}
		}
		dao.execute("update hr_paper_release set release_status=? where id=?",ReleaseStatusEnum.DISTRIBUTED.code(),id);
		return ErrorDesc.success();
	}



	@Override
	public Result cancel(String id) {
		PaperRelease release=this.getById(id);
		if(ReleaseStatusEnum.NOT_DISTRIBUTE.code().equals(release.getReleaseStatus())){
			dao.execute("update hr_paper_release set release_status=? where id=?",ReleaseStatusEnum.CANCEL.code(),id);
		}else if(ReleaseStatusEnum.DISTRIBUTED.code().equals(release.getReleaseStatus())){
			dao.execute("update hr_paper_task set status=?,paper_status=? where paper_release_id=?",ReleaseStatusEnum.CANCEL.code(),PaperTaskResultStatusEnum.CANCEL.code(),id);
			dao.execute("update hr_paper_release set release_status=? where id=?",ReleaseStatusEnum.CANCEL.code(),id);
		}else if(ReleaseStatusEnum.CANCEL.code().equals(release.getReleaseStatus())){
			return ErrorDesc.failureMessage("已作废");
		}
		return ErrorDesc.success();
	}

	/**
	 * 添加，如果语句错误，则抛出异常
	 * @param paperRelease 数据对象
	 * @return 插入是否成功
	 * */
	@Override
	public Result insert(PaperRelease paperRelease) {
		return this.insert(paperRelease,true);
	}

	/**
	 * 批量插入实体，事务内
	 * @param paperReleaseList 实体数据清单
	 * @return 插入是否成功
	 * */
	@Override
	public Result insertList(List<PaperRelease> paperReleaseList) {

		return super.insertList(paperReleaseList);
	}

	
	/**
	 * 按主键删除考试下发
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdPhysical(String id) {
		PaperRelease paperRelease = new PaperRelease();
		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		paperRelease.setId(id);
		try {
			boolean suc = dao.deleteEntity(paperRelease);
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}
	
	/**
	 * 按主键删除考试下发
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdLogical(String id) {
		PaperRelease paperRelease = new PaperRelease();
		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		paperRelease.setId(id);
		paperRelease.setDeleted(true);
		paperRelease.setDeleteBy((String)dao.getDBTreaty().getLoginUserId());
		paperRelease.setDeleteTime(new Date());
		try {
			boolean suc = dao.updateEntity(paperRelease,SaveMode.NOT_NULL_FIELDS);
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}

	/**
	 * 更新，如果执行错误，则抛出异常
	 * @param paperRelease 数据对象
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(PaperRelease paperRelease , SaveMode mode) {
		return this.update(paperRelease,mode,true);
	}

	/**
	 * 更新，根据 throwsException 参数抛出异常或返回 Result 对象
	 * @param paperRelease 数据对象
	 * @param mode 保存模式
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(PaperRelease paperRelease , SaveMode mode,boolean throwsException) {
		Result r=super.update(paperRelease , mode , throwsException);
		if(r.isSuccess()) {
			dao.execute("delete from sys_mapping_owner where owner_id=?",paperRelease.getId());
			if(paperRelease.getSelectUserIds()!=null) {
				for (int i = 0; i < paperRelease.getSelectUserIds().size(); i++) {
					if(!StringUtil.isBlank(paperRelease.getSelectUserIds().get(i))) {
						dao.execute("insert into sys_mapping_owner(id,owner_id,selected_code,owner) values (?,?,?,?)", IDGenerator.getSnowflakeIdString(), paperRelease.getId(), paperRelease.getSelectUserIds().get(i), "user");
					}
				}
			}
			if(paperRelease.getSelectOrgIds()!=null){
				for(int i=0;i<paperRelease.getSelectOrgIds().size();i++) {
					if(!StringUtil.isBlank(paperRelease.getSelectOrgIds().get(i))) {
						dao.execute("insert into sys_mapping_owner(id,owner_id,selected_code,owner) values (?,?,?,?)", IDGenerator.getSnowflakeIdString(), paperRelease.getId(), paperRelease.getSelectOrgIds().get(i), "org");
					}
				}
			}
		}
		return r;
	}

	/**
	 * 更新实体集，事务内
	 * @param paperReleaseList 数据对象列表
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result updateList(List<PaperRelease> paperReleaseList , SaveMode mode) {
		return super.updateList(paperReleaseList , mode);
	}

	
	/**
	 * 按主键更新考试下发
	 *
	 * @param id 主键
	 * @return 是否更新成功
	 */
	public boolean update(DBField field,Object value , String id) {
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		if(!field.table().name().equals(this.table())) throw new IllegalArgumentException("更新的数据表["+field.table().name()+"]与服务对应的数据表["+this.table()+"]不一致");
		int suc=dao.update(field.table().name()).set(field.name(), value).where().and("id = ? ",id).top().execute();
		return suc>0;
	}

	
	/**
	 * 按主键获取考试下发
	 *
	 * @param id 主键
	 * @return PaperRelease 数据对象
	 */
	public PaperRelease getById(String id) {
		PaperRelease sample = new PaperRelease();
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		sample.setId(id);
		return dao.queryEntity(sample);
	}

	/**
	 * 等价于 queryListByIds
	 * */
	@Override
	public List<PaperRelease> getByIds(List<String> ids) {
		return this.queryListByIds(ids);
	}

	@Override
	public List<PaperRelease> queryListByIds(List<String> ids) {
		return super.queryListByUKeys("id",ids);
	}

	@Override
	public Map<String, PaperRelease> queryMapByIds(List<String> ids) {
		return super.queryMapByUKeys("id",ids, PaperRelease::getId);
	}



	/**
	 * 查询实体集合，默认情况下，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @return 查询结果
	 * */
	@Override
	public List<PaperRelease> queryList(PaperReleaseVO sample) {
		return super.queryList(sample);
	}


	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<PaperRelease> queryPagedList(PaperReleaseVO sample, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, pageSize, pageIndex);
	}

	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param condition 其它条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<PaperRelease> queryPagedList(PaperRelease sample, ConditionExpr condition, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, condition, pageSize, pageIndex);
	}

	/**
	 * 检查 实体 是否已经存在 , 判断 主键值不同，但指定字段的值相同的记录是否存在
	 *
	 * @param paperRelease 数据对象
	 * @return 判断结果
	 */
	public Boolean checkExists(PaperRelease paperRelease) {
		//TDOD 此处添加判断段的代码
		//boolean exists=super.checkExists(paperRelease, SYS_ROLE.NAME);
		//return exists;
		return false;
	}

	/**
	 * 批量检查引用
	 * @param ids  检查这些ID是否又被外部表引用
	 * */
	@Override
	public <T> Map<T, ReferCause> hasRefers(List<T> ids) {
		// 默认无业务逻辑，返回此行；有业务逻辑需要校验时，请修改并使用已注释的行代码！！！
		return MapUtil.asMap(ids,new ReferCause(false));
		// return super.hasRefers(FoxnicWeb.BPM_PROCESS_INSTANCE.FORM_DEFINITION_ID,ids);
	}





}